package com.pace.gonu.play;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.view.RedirectView;

import com.pace.gonu.constants.GameType;
import com.pace.gonu.model.chnl.PlayChannel;
import com.pace.gonu.util.AuthKeyGenerator;

/**
 * Handles requests for the application home page.
 */
@Controller
@RequestMapping(value = "/gonu/play")
public class PlayController {
	private static final Logger LOG = LoggerFactory.getLogger(PlayController.class);
	@Autowired
	private PlayService playService;
	private final String CHANNEL_NUMBER = "CHANNEL_NUMBER";
	private final String ORDER = "ORDER";
	private final String AUTH_KEY = "AUTH_KEY";
	private final String NAME = "NAME";

	@RequestMapping(value = "/view.gonu", method = RequestMethod.GET)
	public ModelAndView view(HttpSession session, HttpServletRequest request) {
		ModelAndView mav = new ModelAndView();
		PlayChannel playChannel;
		try {
			playChannel = playService.getChannel((Integer)session.getAttribute(CHANNEL_NUMBER));
			mav.addObject("playChannel", playChannel);
			mav.addObject(ORDER, session.getAttribute(ORDER));
			mav.addObject(NAME, session.getAttribute(NAME));
		} catch (Exception e) {
			LOG.error(e.getMessage());
			return redirectChnlSelect(mav, (String)session.getAttribute(NAME));
		}

		if (GameType.HOBAK.equals(playChannel.getGameTypeObject())) {
			mav.setViewName("/play/viewHobak");
		} else if (GameType.CHARM.equals(playChannel.getGameTypeObject())) {
			mav.setViewName("/play/viewCharm");
		}
		
		return mav;
	}

	@RequestMapping(value = "/waiting.gonu", method = RequestMethod.GET)
	public ModelAndView waiting(HttpSession session, HttpServletRequest request, int channelNumber, String gameType) {
		ModelAndView mav = new ModelAndView();
		String authKey = AuthKeyGenerator.generate(request.getRemoteAddr());
		String name = (String)session.getAttribute(NAME);
		try {
			session.setAttribute(ORDER, playService.join(channelNumber, authKey, name, gameType));
		} catch (IllegalArgumentException e) {
			return redirectChnlSelect(mav, (String)session.getAttribute(NAME));
		}

		session.setAttribute(AUTH_KEY, authKey);
		session.setAttribute(CHANNEL_NUMBER, channelNumber);

		PlayChannel playChannel = playService.getChannel(channelNumber);
		if (playChannel.isPVC()) {
			RedirectView rv = new RedirectView("/gonu/play/view.gonu");
			mav.setView(rv);
			return mav;
		}

		playChannel.setSelectGameType(false);
		mav.addObject("chnlNumber", channelNumber);
		mav.setViewName("/play/waiting");
		return mav;
	}

	@RequestMapping(value = "/chnlSelect.gonu", method = RequestMethod.GET)
	public ModelAndView chnlSelect(HttpSession session, String name, boolean isPvc) {
		ModelAndView mav = new ModelAndView();
		if (StringUtils.isBlank(name) || name.length() > 3) {
			mav.setViewName("/play/home");
			return mav;
		}
		session.setAttribute(NAME, name);

		if (isPvc) {
			PlayChannel playChannel = playService.getStartChannel();
			playChannel.setPVC(true);
			RedirectView rv = new RedirectView("/gonu/play/typeSelect.gonu?channelNumber=" + playChannel.getChnlNumber() + "&isPvc=true");
			mav.setView(rv);
			return mav;
		}
		
		mav.addObject("playChannels", playService.getChannels());
		mav.setViewName("/play/chnlSelect");
		return mav;
	}

	@RequestMapping(value = "/typeSelect.gonu", method = RequestMethod.GET)
	public ModelAndView typeSelect(HttpSession session, int channelNumber, boolean isPvc) {
		ModelAndView mav = new ModelAndView();
		PlayChannel playChannel = playService.getChannel(channelNumber);
		if (playChannel.isSelectGameType()) {
			return redirectChnlSelect(mav, (String)session.getAttribute(NAME));
		} else if (!isPvc && playChannel.isPVC()) {
			return redirectChnlSelect(mav, (String)session.getAttribute(NAME));
		}

		playChannel.setSelectGameType(true);
		if (StringUtils.isNotBlank(playChannel.getFirstUser())) {
			if (isPvc) {
				RedirectView rv = new RedirectView("/gonu/home.gonu");
				mav.setView(rv);
				return mav;
			} else {
				RedirectView rv = new RedirectView("/gonu/play/waiting.gonu?channelNumber=" + channelNumber);
				mav.setView(rv);
				return mav;
			}

		}
		mav.addObject("channelNumber", channelNumber);
		mav.setViewName("/play/gameTypeSelect");
		return mav;
	}

	private ModelAndView redirectChnlSelect(ModelAndView mav, String name) {
		RedirectView rv = new RedirectView("/play/chnlSelect.gonu?name=" + name);
		mav.setView(rv);
		return mav;
	}

}
